package cz.proks.schoolpupilbook.gae.dao;

import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.EntityTransaction;
import javax.persistence.Persistence;

public class PersistenceManager {
	private final static EntityManagerFactory EMF = Persistence.createEntityManagerFactory("transactions-optional");
			
	public static <T> T execute(PersistenceExecutor<T> exec, boolean inTransaction) {		
		final EntityManager em = getEntityManager();
		return inTransaction ? executeInTransaction(em, exec) : 
							   executeWithoutTransaction(em, exec);		
	}	
	
	private static <T> T executeInTransaction(final EntityManager em, final PersistenceExecutor<T> exec) {		
		final EntityTransaction tr = em.getTransaction();
		tr.begin();
		try {
			T obj = exec.doExecute(em);
			tr.commit();			
			return obj;
		} catch (Exception e) {
			tr.rollback();
			e.printStackTrace();			
			return null;
		} finally {			
			em.close();
		}
	}
	
	private static <T> T executeWithoutTransaction(final EntityManager em, final PersistenceExecutor<T> exec) {
		try {
			T obj = exec.doExecute(em);
			return obj;
		} catch (Exception e) {		
			e.printStackTrace();			
			return null;
		} finally {			
			em.close();
		}
	}
	
	private static EntityManagerFactory getInstance() {
		return EMF;
	}
	
	private static EntityManager getEntityManager() {
		return getInstance().createEntityManager();
	}
	
	private PersistenceManager() {}
	
	public static interface PersistenceExecutor<T> {
		T doExecute(EntityManager em);
	} 
}
